#ifndef MYIOCTL_H
#define MYIOCTL_H

#include "MyPacketProcessor.h"

union MY_USB_HUB_CAP_FLAGS
{
	unsigned long ul;
	struct
	{
		unsigned long HubIsHighSpeedCapable  :1;
		unsigned long HubIsHighSpeed  :1;
		unsigned long HubIsMultiTtCapable  :1;
		unsigned long HubIsMultiTt  :1;
		unsigned long HubIsRoot  :1;
		unsigned long HubIsArmedWakeOnConnect  :1;
		unsigned long HubIsBusPowered  :1;
		unsigned long ReservedMBZ  :25;
	};
};

struct MY_USB_HUB_DESCRIPTOR
{
	unsigned char  bDescriptorLength;
	unsigned char  bDescriptorType;
	unsigned char  bNumberOfPorts;
	unsigned short wHubCharacteristics;
	unsigned char  bPowerOnToPowerGood;
	unsigned char  bHubControlCurrent;
};

struct MY_GUID
{
	unsigned long  Data1;
	unsigned short Data2;
	unsigned short Data3;
	unsigned char  Data4[8];
};

struct MY_USB_HUB_DEVICE_UXD_SETTINGS
{
	unsigned long   Version;
	MY_GUID         PnpGuid;
	MY_GUID         OwnerGuid;
	unsigned long   DeleteOnShutdown;
	unsigned long   DeleteOnReload;
	unsigned long   DeleteOnDisconnect;
};

struct MY_USB_HUB_INFORMATION
{
	MY_USB_HUB_DESCRIPTOR HubDescriptor;
	bool HubIsBusPowered;
};

enum MY_USB_HUB_NODE
{
	UsbHub,
	UsbMIParent
};

struct MY_USB_DEVICE_DESCRIPTOR
{
	unsigned char  bLength;
	unsigned char  bDescriptorType;
	unsigned short bcdUSB;
	unsigned char  bDeviceClass;
	unsigned char  bDeviceSubClass;
	unsigned char  bDeviceProtocol;
	unsigned char  bMaxPacketSize0;
	unsigned short idVendor;
	unsigned short idProduct;
	unsigned short bcdDevice;
	unsigned char  iManufacturer;
	unsigned char  iProduct;
	unsigned char  iSerialNumber;
	unsigned char  bNumConfigurations;
};

enum MY_USB_CONNECTION_STATUS
{
	NoDeviceConnected          = 0,
	DeviceConnected            = 1,
	DeviceFailedEnumeration    = 2,
	DeviceGeneralFailure       = 3,
	DeviceCausedOvercurrent    = 4,
	DeviceNotEnoughPower       = 5,
	DeviceNotEnoughBandwidth   = 6,
	DeviceHubNestedTooDeeply   = 7,
	DeviceInLegacyHub          = 8,
	DeviceEnumerating          = 9,
	DeviceReset                = 10 
};

struct MY_USB_ENDPOINT_DESCRIPTOR
{
	unsigned char  bLength;
	unsigned char  bDescriptorType;
	unsigned char  bEndpointAddress;
	unsigned char  bmAttributes;
	unsigned short wMaxPacketSize;
	unsigned char  bInterval;
};

struct MY_USB_PIPE_INFO
{
	MY_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
	unsigned long ScheduleOffset;
};

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////


class MY_IOCTL_EMPTY : public MyPacket
{
public:
	void DeserializeEmpty(void *pBuffer, long bufSize, unsigned char type);
	virtual void Deserialize(void *pBuffer, long bufSize, unsigned char packType){}
	//std::wstring GetPacketName(){return packetName;}
	virtual std::wstring GetDetailedInfo();

protected:
	//std::wstring packetName;
	bool isCompleted;
	int status;
	MyBuffer buffer;
};

class MY_IOCTL_INTERNAL_USB_GET_BUS_INFO : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long TotalBandwidth;
	unsigned long ConsumedBandwidth;
	unsigned long ControllerNameLength;
};

class MY_IOCTL_INTERNAL_USB_GET_CONTROLLER_NAME : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long ActualLength;
	std::auto_ptr<wchar_t> HubName;
};

class MY_IOCTL_INTERNAL_USB_GET_DEVICE_CONFIG_INFO : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long                  Version;
	unsigned long                  Length;
	MY_USB_HUB_CAP_FLAGS           HubFlags;
	unsigned                       HardwareIdsLen;
	unsigned                       CompatibleIdsLen;
	unsigned                       DeviceDescriptionLen;
	std::auto_ptr<wchar_t>         HardwareIds;
	std::auto_ptr<wchar_t>         CompatibleIds;
	std::auto_ptr<wchar_t>         DeviceDescription;
	MY_USB_HUB_DEVICE_UXD_SETTINGS UxdSettings;

	void DeserializeUsbIdString(std::auto_ptr<wchar_t> &pStr, unsigned &strLen);
	void DeserializeGUID(MY_GUID &guid);
};

class MY_IOCTL_INTERNAL_USB_GET_TOPOLOGY_ADDRESS : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long  PciBusNumber;
	unsigned long  PciDeviceNumber;
	unsigned long  PciFunctionNumber;
	unsigned short RootHubPortNumber;
	unsigned short HubPortNumber[5];
};

class MY_IOCTL_INTERNAL_USB_GET_HUB_NAME : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long ActualLength;
	std::auto_ptr<wchar_t> HubName;
};

class MY_IOCTL_INTERNAL_USB_GET_PORT_STATUS : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long portStatusFlags;
};

class MY_IOCTL_USB_GET_HUB_CAPABILITIES : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	bool HubIs2xCapable;
};

class MY_IOCTL_USB_GET_HUB_CAPABILITIES_EX : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	MY_USB_HUB_CAP_FLAGS HubFlags;
};

class MY_IOCTL_USB_GET_NODE_CONNECTION_NAME : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long ConnectionIndex;
	unsigned long ActualLength;
	std::auto_ptr<wchar_t> NodeName;
};

class MY_IOCTL_USB_GET_NODE_INFORMATION : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	MY_USB_HUB_NODE NodeType;
	union
	{
		MY_USB_HUB_INFORMATION HubInformation;
		unsigned long NumberOfInterfaces;
	} u;
};

class MY_IOCTL_USB_GET_NODE_CONNECTION_INFORMATION : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long            ConnectionIndex;
	MY_USB_DEVICE_DESCRIPTOR DeviceDescriptor;
	unsigned char            CurrentConfigurationValue;
	bool                     LowSpeed;
	bool                     DeviceIsHub;
	unsigned short           DeviceAddress;
	unsigned long            NumberOfOpenPipes;

	MY_USB_CONNECTION_STATUS ConnectionStatus;
	std::auto_ptr<MY_USB_PIPE_INFO> PipeList;
};

class MY_IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX : public MY_IOCTL_EMPTY
{
public:
	void Deserialize(void *pBuffer, long bufSize, unsigned char packType);
	std::wstring GetDetailedInfo();

private:
	unsigned long            ConnectionIndex;
	MY_USB_DEVICE_DESCRIPTOR DeviceDescriptor;
	unsigned char            CurrentConfigurationValue;
	unsigned char            Speed;
	bool                     DeviceIsHub;
	unsigned short           DeviceAddress;
	unsigned long            NumberOfOpenPipes;

	MY_USB_CONNECTION_STATUS ConnectionStatus;
	std::auto_ptr<MY_USB_PIPE_INFO> PipeList;
};

#endif // MYIOCTL_H